From: Cosimo Cecchi Date: Wed, 3 Apr 2013 18:16:58 +0000 (-0400) Subject: shell-app: track the busy state of GApplications X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~4329 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=45026df4bd6bc6caaa5c59ae8c98bd95cc4192d7;p=gnome-shell.git shell-app: track the busy state of GApplications Watch for property changes on the org.gtk.Application interface, and transition the state to BUSY when the corresponding property is flipped on. https://bugzilla.gnome.org/show_bug.cgi?id=697207 --- diff --git a/src/shell-app.c b/src/shell-app.c index 546257332..9980d3989 100644 --- a/src/shell-app.c +++ b/src/shell-app.c @@ -39,6 +39,9 @@ typedef struct { /* Whether or not we need to resort the windows; this is done on demand */ gboolean window_sort_stale : 1; + /* DBus property notification subscription */ + guint properties_changed_id : 1; + /* See GApplication documentation */ GDBusMenuModel *remote_menu; GActionMuxer *muxer; @@ -959,6 +962,84 @@ shell_app_on_ws_switch (MetaScreen *screen, g_signal_emit (app, shell_app_signals[WINDOWS_CHANGED], 0); } +static void +application_properties_changed (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + ShellApp *app = user_data; + GVariant *changed_properties; + GVariantIter iter; + gboolean busy = FALSE; + const gchar *key, *interface_name_for_signal; + GVariant *value; + + g_variant_get (parameters, + "(&s@a{sv}as)", + &interface_name_for_signal, + &changed_properties, + NULL); + + if (g_strcmp0 (interface_name_for_signal, "org.gtk.Application") != 0) + return; + + g_variant_iter_init (&iter, changed_properties); + while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) + { + if (g_strcmp0 (key, "Busy") != 0) + { + g_variant_unref (value); + continue; + } + + busy = g_variant_get_boolean (value); + g_variant_unref (value); + break; + } + + if (busy) + shell_app_state_transition (app, SHELL_APP_STATE_BUSY); + else + shell_app_state_transition (app, SHELL_APP_STATE_RUNNING); + + if (changed_properties != NULL) + g_variant_unref (changed_properties); +} + +static void +shell_app_ensure_busy_watch (ShellApp *app) +{ + ShellAppRunningState *running_state = app->running_state; + MetaWindow *window; + const gchar *object_path; + + if (running_state->properties_changed_id != 0) + return; + + if (running_state->unique_bus_name == NULL) + return; + + window = g_slist_nth_data (running_state->windows, 0); + object_path = meta_window_get_gtk_application_object_path (window); + + if (object_path == NULL) + return; + + running_state->properties_changed_id = + g_dbus_connection_signal_subscribe (running_state->session, + running_state->unique_bus_name, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + object_path, + "org.gtk.Application", + G_DBUS_SIGNAL_FLAGS_NONE, + application_properties_changed, app, NULL); +} + void _shell_app_add_window (ShellApp *app, MetaWindow *window) @@ -977,6 +1058,7 @@ _shell_app_add_window (ShellApp *app, g_signal_connect (window, "notify::user-time", G_CALLBACK(shell_app_on_user_time_changed), app); shell_app_update_app_menu (app, window); + shell_app_ensure_busy_watch (app); if (app->state != SHELL_APP_STATE_STARTING) shell_app_state_transition (app, SHELL_APP_STATE_RUNNING); @@ -1279,6 +1361,9 @@ unref_running_state (ShellAppRunningState *state) screen = shell_global_get_screen (shell_global_get ()); g_signal_handler_disconnect (screen, state->workspace_switch_id); + if (state->properties_changed_id != 0) + g_dbus_connection_signal_unsubscribe (state->session, state->properties_changed_id); + g_clear_object (&state->remote_menu); g_clear_object (&state->muxer); g_clear_object (&state->session); diff --git a/src/shell-app.h b/src/shell-app.h index 6bf707a87..3009d8ff7 100644 --- a/src/shell-app.h +++ b/src/shell-app.h @@ -31,7 +31,8 @@ struct _ShellAppClass typedef enum { SHELL_APP_STATE_STOPPED, SHELL_APP_STATE_STARTING, - SHELL_APP_STATE_RUNNING + SHELL_APP_STATE_RUNNING, + SHELL_APP_STATE_BUSY } ShellAppState; GType shell_app_get_type (void) G_GNUC_CONST;